import os
import time
import cv2
import numpy as np
import pandas as pd
from keras.applications.resnet import ResNet50, preprocess_input
from keras.preprocessing import image
from keras.models import Model, Sequential
from keras.layers import Dense, Flatten, BatchNormalization, Dropout, Concatenate, Input
from sklearn.metrics import classification_report, roc_curve, auc
import matplotlib.pyplot as plt
from keras.utils import to_categorical
from keras.optimizers import Adam
from keras.losses import categorical_crossentropy
from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
from sklearn.preprocessing import StandardScaler

# Load ResNet50 model
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
x = base_model.output
x = Flatten()(x)
x = BatchNormalization()(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
image_output = Dense(256, activation='relu')(x)  # new output layer for image features

# Freeze the layers except the last few layers
for layer in base_model.layers[:-10]:
    layer.trainable = False

# Function to detect and crop chest area
def detect_and_crop_chest(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    chest_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_fullbody.xml')
    chests = chest_cascade.detectMultiScale(gray, 1.1, 4)
    for (x, y, w, h) in chests:
        return image[y:y+h, x:x+w]
    return image  # return original image if no chest is detected

# Load and preprocess images
def load_images_from_folder(folder):
    images = []
    for filename in os.listdir(folder):
        img = cv2.imread(os.path.join(folder, filename))
        if img is not None:
            img = detect_and_crop_chest(img)
            img = cv2.resize(img, (224, 224))
            images.append(img)
    return images

# Load and preprocess text data
def load_text_data(csv_file):
    df = pd.read_csv(csv_file)
    text_data = df[['SCC', 'CEA', 'CK19', 'NSE', 'ProGRP']].values
    labels = df['Lung_cancer'].values
    return text_data, labels

# Load training images and text data
train_dir = 'D:\\kaggle\\final\\data1\\train'
cancer_train_dir = os.path.join(train_dir, 'cancer')
normal_train_dir = os.path.join(train_dir, 'normal')

cancer_train_images = load_images_from_folder(cancer_train_dir)
normal_train_images = load_images_from_folder(normal_train_dir)

cancer_train_text, cancer_train_labels = load_text_data(os.path.join(cancer_train_dir, 'data.csv'))
normal_train_text, normal_train_labels = load_text_data(os.path.join(normal_train_dir, 'data.csv'))

# Load testing images and text data
test_dir = 'D:\\kaggle\\final\\data1\\test'
cancer_test_dir = os.path.join(test_dir, 'cancer')
normal_test_dir = os.path.join(test_dir, 'normal')

cancer_test_images = load_images_from_folder(cancer_test_dir)
normal_test_images = load_images_from_folder(normal_test_dir)

cancer_test_text, cancer_test_labels = load_text_data(os.path.join(cancer_test_dir, 'data.csv'))
normal_test_text, normal_test_labels = load_text_data(os.path.join(normal_test_dir, 'data.csv'))

# Combine data
X_train_images = np.array(cancer_train_images + normal_train_images)
X_train_text = np.vstack((cancer_train_text, normal_train_text))
y_train = np.array(cancer_train_labels.tolist() + normal_train_labels.tolist())

X_test_images = np.array(cancer_test_images + normal_test_images)
X_test_text = np.vstack((cancer_test_text, normal_test_text))
y_test = np.array(cancer_test_labels.tolist() + normal_test_labels.tolist())

# Preprocess images
X_train_images = preprocess_input(X_train_images)
X_test_images = preprocess_input(X_test_images)

# Standardize text data
scaler = StandardScaler()
X_train_text = scaler.fit_transform(X_train_text)
X_test_text = scaler.transform(X_test_text)

# Apply importance weights to text data
importance_weights = np.array([0.08404119, 0.15410762, 0.24459628, 0.40112669, 0.11612822])
X_train_text = X_train_text * importance_weights
X_test_text = X_test_text * importance_weights

# Convert labels to categorical
y_train = to_categorical(y_train, num_classes=2)
y_test = to_categorical(y_test, num_classes=2)

# Define text input model
text_input = Input(shape=(5,))
text_x = Dense(128, activation='relu')(text_input)
text_x = Dropout(0.5)(text_x)
text_output = Dense(256, activation='relu')(text_x)

# Combine image and text models
combined = Concatenate()([image_output, text_output])
combined = Dense(512, activation='relu')(combined)
combined = Dropout(0.5)(combined)
final_output = Dense(2, activation='softmax')(combined)

# Create the final model
model = Model(inputs=[base_model.input, text_input], outputs=final_output)

# Compile the model
model.compile(optimizer=Adam(learning_rate=0.0001), loss=categorical_crossentropy, metrics=['accuracy'])

# Print the model summary
model.summary()

# Callbacks
checkpoint_dir = './checkpoints'
os.makedirs(checkpoint_dir, exist_ok=True)

checkpoint = ModelCheckpoint(filepath=os.path.join(checkpoint_dir, 'chest_CT_SCAN-ResNet50.h5'),
                             monitor='val_loss',
                             mode='auto',
                             save_best_only=True)
early_stopping = EarlyStopping(verbose=1, patience=5)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, min_lr=0.00001)

# Train model
start_time = time.time()
history = model.fit([X_train_images, X_train_text], y_train, epochs=100, validation_data=([X_test_images, X_test_text], y_test),
                    callbacks=[checkpoint, early_stopping, reduce_lr])
end_time = time.time()

# Predict on test set
y_pred = model.predict([X_test_images, X_test_text])

# Convert predictions to labels
y_pred_labels = np.argmax(y_pred, axis=1)
y_test_labels = np.argmax(y_test, axis=1)

# Print classification report
print(classification_report(y_test_labels, y_pred_labels))

# Calculate and plot ROC curve and AUC
fpr, tpr, _ = roc_curve(y_test_labels, y_pred_labels)
roc_auc = auc(fpr, tpr)
plt.figure()
plt.plot(fpr, tpr, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], 'k--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()

# Print program running time
print(f'Program running time: {end_time - start_time}')

'''
Model: "model"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to                     
==================================================================================================
 input_1 (InputLayer)           [(None, 224, 224, 3  0           []                               
                                )]                                                                

 conv1_pad (ZeroPadding2D)      (None, 230, 230, 3)  0           ['input_1[0][0]']                

 conv1_conv (Conv2D)            (None, 112, 112, 64  9472        ['conv1_pad[0][0]']              
                                )                                                                 

 conv1_bn (BatchNormalization)  (None, 112, 112, 64  256         ['conv1_conv[0][0]']             
                                )                                                                 

 conv1_relu (Activation)        (None, 112, 112, 64  0           ['conv1_bn[0][0]']               
                                )                                                                 

 pool1_pad (ZeroPadding2D)      (None, 114, 114, 64  0           ['conv1_relu[0][0]']             
                                )                                                                 

 pool1_pool (MaxPooling2D)      (None, 56, 56, 64)   0           ['pool1_pad[0][0]']              

 conv2_block1_1_conv (Conv2D)   (None, 56, 56, 64)   4160        ['pool1_pool[0][0]']             

 conv2_block1_1_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block1_1_conv[0][0]']    
 ization)                                                                                         

 conv2_block1_1_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block1_1_bn[0][0]']      
 n)                                                                                               

 conv2_block1_2_conv (Conv2D)   (None, 56, 56, 64)   36928       ['conv2_block1_1_relu[0][0]']    

 conv2_block1_2_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block1_2_conv[0][0]']    
 ization)                                                                                         

 conv2_block1_2_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block1_2_bn[0][0]']      
 n)                                                                                               

 conv2_block1_0_conv (Conv2D)   (None, 56, 56, 256)  16640       ['pool1_pool[0][0]']             

 conv2_block1_3_conv (Conv2D)   (None, 56, 56, 256)  16640       ['conv2_block1_2_relu[0][0]']    

 conv2_block1_0_bn (BatchNormal  (None, 56, 56, 256)  1024       ['conv2_block1_0_conv[0][0]']    
 ization)                                                                                         

 conv2_block1_3_bn (BatchNormal  (None, 56, 56, 256)  1024       ['conv2_block1_3_conv[0][0]']    
 ization)                                                                                         

 conv2_block1_add (Add)         (None, 56, 56, 256)  0           ['conv2_block1_0_bn[0][0]',      
                                                                  'conv2_block1_3_bn[0][0]']      

 conv2_block1_out (Activation)  (None, 56, 56, 256)  0           ['conv2_block1_add[0][0]']       

 conv2_block2_1_conv (Conv2D)   (None, 56, 56, 64)   16448       ['conv2_block1_out[0][0]']       

 conv2_block2_1_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block2_1_conv[0][0]']    
 ization)                                                                                         

 conv2_block2_1_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block2_1_bn[0][0]']      
 n)                                                                                               

 conv2_block2_2_conv (Conv2D)   (None, 56, 56, 64)   36928       ['conv2_block2_1_relu[0][0]']    

 conv2_block2_2_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block2_2_conv[0][0]']    
 ization)                                                                                         

 conv2_block2_2_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block2_2_bn[0][0]']      
 n)                                                                                               

 conv2_block2_3_conv (Conv2D)   (None, 56, 56, 256)  16640       ['conv2_block2_2_relu[0][0]']    

 conv2_block2_3_bn (BatchNormal  (None, 56, 56, 256)  1024       ['conv2_block2_3_conv[0][0]']    
 ization)                                                                                         

 conv2_block2_add (Add)         (None, 56, 56, 256)  0           ['conv2_block1_out[0][0]',       
                                                                  'conv2_block2_3_bn[0][0]']      

 conv2_block2_out (Activation)  (None, 56, 56, 256)  0           ['conv2_block2_add[0][0]']       

 conv2_block3_1_conv (Conv2D)   (None, 56, 56, 64)   16448       ['conv2_block2_out[0][0]']       

 conv2_block3_1_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block3_1_conv[0][0]']    
 ization)                                                                                         

 conv2_block3_1_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block3_1_bn[0][0]']      
 n)                                                                                               

 conv2_block3_2_conv (Conv2D)   (None, 56, 56, 64)   36928       ['conv2_block3_1_relu[0][0]']    

 conv2_block3_2_bn (BatchNormal  (None, 56, 56, 64)  256         ['conv2_block3_2_conv[0][0]']    
 ization)                                                                                         

 conv2_block3_2_relu (Activatio  (None, 56, 56, 64)  0           ['conv2_block3_2_bn[0][0]']      
 n)                                                                                               

 conv2_block3_3_conv (Conv2D)   (None, 56, 56, 256)  16640       ['conv2_block3_2_relu[0][0]']    

 conv2_block3_3_bn (BatchNormal  (None, 56, 56, 256)  1024       ['conv2_block3_3_conv[0][0]']    
 ization)                                                                                         

 conv2_block3_add (Add)         (None, 56, 56, 256)  0           ['conv2_block2_out[0][0]',       
                                                                  'conv2_block3_3_bn[0][0]']      

 conv2_block3_out (Activation)  (None, 56, 56, 256)  0           ['conv2_block3_add[0][0]']       

 conv3_block1_1_conv (Conv2D)   (None, 28, 28, 128)  32896       ['conv2_block3_out[0][0]']       

 conv3_block1_1_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block1_1_conv[0][0]']    
 ization)                                                                                         

 conv3_block1_1_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block1_1_bn[0][0]']      
 n)                                                                                               

 conv3_block1_2_conv (Conv2D)   (None, 28, 28, 128)  147584      ['conv3_block1_1_relu[0][0]']    

 conv3_block1_2_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block1_2_conv[0][0]']    
 ization)                                                                                         

 conv3_block1_2_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block1_2_bn[0][0]']      
 n)                                                                                               

 conv3_block1_0_conv (Conv2D)   (None, 28, 28, 512)  131584      ['conv2_block3_out[0][0]']       

 conv3_block1_3_conv (Conv2D)   (None, 28, 28, 512)  66048       ['conv3_block1_2_relu[0][0]']    

 conv3_block1_0_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block1_0_conv[0][0]']    
 ization)                                                                                         

 conv3_block1_3_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block1_3_conv[0][0]']    
 ization)                                                                                         

 conv3_block1_add (Add)         (None, 28, 28, 512)  0           ['conv3_block1_0_bn[0][0]',      
                                                                  'conv3_block1_3_bn[0][0]']      

 conv3_block1_out (Activation)  (None, 28, 28, 512)  0           ['conv3_block1_add[0][0]']       

 conv3_block2_1_conv (Conv2D)   (None, 28, 28, 128)  65664       ['conv3_block1_out[0][0]']       

 conv3_block2_1_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block2_1_conv[0][0]']    
 ization)                                                                                         

 conv3_block2_1_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block2_1_bn[0][0]']      
 n)                                                                                               

 conv3_block2_2_conv (Conv2D)   (None, 28, 28, 128)  147584      ['conv3_block2_1_relu[0][0]']    

 conv3_block2_2_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block2_2_conv[0][0]']    
 ization)                                                                                         

 conv3_block2_2_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block2_2_bn[0][0]']      
 n)                                                                                               

 conv3_block2_3_conv (Conv2D)   (None, 28, 28, 512)  66048       ['conv3_block2_2_relu[0][0]']    

 conv3_block2_3_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block2_3_conv[0][0]']    
 ization)                                                                                         

 conv3_block2_add (Add)         (None, 28, 28, 512)  0           ['conv3_block1_out[0][0]',       
                                                                  'conv3_block2_3_bn[0][0]']      

 conv3_block2_out (Activation)  (None, 28, 28, 512)  0           ['conv3_block2_add[0][0]']       

 conv3_block3_1_conv (Conv2D)   (None, 28, 28, 128)  65664       ['conv3_block2_out[0][0]']       

 conv3_block3_1_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block3_1_conv[0][0]']    
 ization)                                                                                         

 conv3_block3_1_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block3_1_bn[0][0]']      
 n)                                                                                               

 conv3_block3_2_conv (Conv2D)   (None, 28, 28, 128)  147584      ['conv3_block3_1_relu[0][0]']    

 conv3_block3_2_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block3_2_conv[0][0]']    
 ization)                                                                                         

 conv3_block3_2_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block3_2_bn[0][0]']      
 n)                                                                                               

 conv3_block3_3_conv (Conv2D)   (None, 28, 28, 512)  66048       ['conv3_block3_2_relu[0][0]']    

 conv3_block3_3_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block3_3_conv[0][0]']    
 ization)                                                                                         

 conv3_block3_add (Add)         (None, 28, 28, 512)  0           ['conv3_block2_out[0][0]',       
                                                                  'conv3_block3_3_bn[0][0]']      

 conv3_block3_out (Activation)  (None, 28, 28, 512)  0           ['conv3_block3_add[0][0]']       

 conv3_block4_1_conv (Conv2D)   (None, 28, 28, 128)  65664       ['conv3_block3_out[0][0]']       

 conv3_block4_1_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block4_1_conv[0][0]']    
 ization)                                                                                         

 conv3_block4_1_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block4_1_bn[0][0]']      
 n)                                                                                               

 conv3_block4_2_conv (Conv2D)   (None, 28, 28, 128)  147584      ['conv3_block4_1_relu[0][0]']    

 conv3_block4_2_bn (BatchNormal  (None, 28, 28, 128)  512        ['conv3_block4_2_conv[0][0]']    
 ization)                                                                                         

 conv3_block4_2_relu (Activatio  (None, 28, 28, 128)  0          ['conv3_block4_2_bn[0][0]']      
 n)                                                                                               

 conv3_block4_3_conv (Conv2D)   (None, 28, 28, 512)  66048       ['conv3_block4_2_relu[0][0]']    

 conv3_block4_3_bn (BatchNormal  (None, 28, 28, 512)  2048       ['conv3_block4_3_conv[0][0]']    
 ization)                                                                                         

 conv3_block4_add (Add)         (None, 28, 28, 512)  0           ['conv3_block3_out[0][0]',       
                                                                  'conv3_block4_3_bn[0][0]']      

 conv3_block4_out (Activation)  (None, 28, 28, 512)  0           ['conv3_block4_add[0][0]']       

 conv4_block1_1_conv (Conv2D)   (None, 14, 14, 256)  131328      ['conv3_block4_out[0][0]']       

 conv4_block1_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block1_1_conv[0][0]']    
 ization)                                                                                         

 conv4_block1_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block1_1_bn[0][0]']      
 n)                                                                                               

 conv4_block1_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block1_1_relu[0][0]']    

 conv4_block1_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block1_2_conv[0][0]']    
 ization)                                                                                         

 conv4_block1_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block1_2_bn[0][0]']      
 n)                                                                                               

 conv4_block1_0_conv (Conv2D)   (None, 14, 14, 1024  525312      ['conv3_block4_out[0][0]']       
                                )                                                                 

 conv4_block1_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block1_2_relu[0][0]']    
                                )                                                                 

 conv4_block1_0_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block1_0_conv[0][0]']    
 ization)                       )                                                                 

 conv4_block1_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block1_3_conv[0][0]']    
 ization)                       )                                                                 

 conv4_block1_add (Add)         (None, 14, 14, 1024  0           ['conv4_block1_0_bn[0][0]',      
                                )                                 'conv4_block1_3_bn[0][0]']      

 conv4_block1_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block1_add[0][0]']       
                                )                                                                 

 conv4_block2_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block1_out[0][0]']       

 conv4_block2_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block2_1_conv[0][0]']    
 ization)                                                                                         

 conv4_block2_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block2_1_bn[0][0]']      
 n)                                                                                               

 conv4_block2_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block2_1_relu[0][0]']    

 conv4_block2_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block2_2_conv[0][0]']    
 ization)                                                                                         

 conv4_block2_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block2_2_bn[0][0]']      
 n)                                                                                               

 conv4_block2_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block2_2_relu[0][0]']    
                                )                                                                 

 conv4_block2_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block2_3_conv[0][0]']    
 ization)                       )                                                                 

 conv4_block2_add (Add)         (None, 14, 14, 1024  0           ['conv4_block1_out[0][0]',       
                                )                                 'conv4_block2_3_bn[0][0]']      

 conv4_block2_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block2_add[0][0]']       
                                )                                                                 

 conv4_block3_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block2_out[0][0]']       

 conv4_block3_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block3_1_conv[0][0]']    
 ization)                                                                                         

 conv4_block3_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block3_1_bn[0][0]']      
 n)                                                                                               

 conv4_block3_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block3_1_relu[0][0]']    

 conv4_block3_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block3_2_conv[0][0]']    
 ization)                                                                                         

 conv4_block3_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block3_2_bn[0][0]']      
 n)                                                                                               

 conv4_block3_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block3_2_relu[0][0]']    
                                )                                                                 

 conv4_block3_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block3_3_conv[0][0]']    
 ization)                       )                                                                 

 conv4_block3_add (Add)         (None, 14, 14, 1024  0           ['conv4_block2_out[0][0]',       
                                )                                 'conv4_block3_3_bn[0][0]']      

 conv4_block3_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block3_add[0][0]']       
                                )                                                                 

 conv4_block4_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block3_out[0][0]']       

 conv4_block4_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block4_1_conv[0][0]']    
 ization)                                                                                         

 conv4_block4_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block4_1_bn[0][0]']      
 n)                                                                                               

 conv4_block4_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block4_1_relu[0][0]']    

 conv4_block4_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block4_2_conv[0][0]']    
 ization)                                                                                         

 conv4_block4_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block4_2_bn[0][0]']      
 n)                                                                                               

 conv4_block4_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block4_2_relu[0][0]']    
                                )                                                                 

 conv4_block4_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block4_3_conv[0][0]']    
 ization)                       )                                                                 

 conv4_block4_add (Add)         (None, 14, 14, 1024  0           ['conv4_block3_out[0][0]',       
                                )                                 'conv4_block4_3_bn[0][0]']      

 conv4_block4_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block4_add[0][0]']       
                                )                                                                 

 conv4_block5_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block4_out[0][0]']       

 conv4_block5_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block5_1_conv[0][0]']    
 ization)                                                                                         

 conv4_block5_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block5_1_bn[0][0]']      
 n)                                                                                               

 conv4_block5_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block5_1_relu[0][0]']    

 conv4_block5_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block5_2_conv[0][0]']    
 ization)                                                                                         

 conv4_block5_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block5_2_bn[0][0]']      
 n)                                                                                               

 conv4_block5_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block5_2_relu[0][0]']    
                                )                                                                 

 conv4_block5_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block5_3_conv[0][0]']    
 ization)                       )                                                                 

 conv4_block5_add (Add)         (None, 14, 14, 1024  0           ['conv4_block4_out[0][0]',       
                                )                                 'conv4_block5_3_bn[0][0]']      

 conv4_block5_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block5_add[0][0]']       
                                )                                                                 

 conv4_block6_1_conv (Conv2D)   (None, 14, 14, 256)  262400      ['conv4_block5_out[0][0]']       

 conv4_block6_1_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block6_1_conv[0][0]']    
 ization)                                                                                         

 conv4_block6_1_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block6_1_bn[0][0]']      
 n)                                                                                               

 conv4_block6_2_conv (Conv2D)   (None, 14, 14, 256)  590080      ['conv4_block6_1_relu[0][0]']    

 conv4_block6_2_bn (BatchNormal  (None, 14, 14, 256)  1024       ['conv4_block6_2_conv[0][0]']    
 ization)                                                                                         

 conv4_block6_2_relu (Activatio  (None, 14, 14, 256)  0          ['conv4_block6_2_bn[0][0]']      
 n)                                                                                               

 conv4_block6_3_conv (Conv2D)   (None, 14, 14, 1024  263168      ['conv4_block6_2_relu[0][0]']    
                                )                                                                 

 conv4_block6_3_bn (BatchNormal  (None, 14, 14, 1024  4096       ['conv4_block6_3_conv[0][0]']    
 ization)                       )                                                                 

 conv4_block6_add (Add)         (None, 14, 14, 1024  0           ['conv4_block5_out[0][0]',       
                                )                                 'conv4_block6_3_bn[0][0]']      

 conv4_block6_out (Activation)  (None, 14, 14, 1024  0           ['conv4_block6_add[0][0]']       
                                )                                                                 

 conv5_block1_1_conv (Conv2D)   (None, 7, 7, 512)    524800      ['conv4_block6_out[0][0]']       

 conv5_block1_1_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block1_1_conv[0][0]']    
 ization)                                                                                         

 conv5_block1_1_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block1_1_bn[0][0]']      
 n)                                                                                               

 conv5_block1_2_conv (Conv2D)   (None, 7, 7, 512)    2359808     ['conv5_block1_1_relu[0][0]']    

 conv5_block1_2_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block1_2_conv[0][0]']    
 ization)                                                                                         

 conv5_block1_2_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block1_2_bn[0][0]']      
 n)                                                                                               

 conv5_block1_0_conv (Conv2D)   (None, 7, 7, 2048)   2099200     ['conv4_block6_out[0][0]']       

 conv5_block1_3_conv (Conv2D)   (None, 7, 7, 2048)   1050624     ['conv5_block1_2_relu[0][0]']    

 conv5_block1_0_bn (BatchNormal  (None, 7, 7, 2048)  8192        ['conv5_block1_0_conv[0][0]']    
 ization)                                                                                         

 conv5_block1_3_bn (BatchNormal  (None, 7, 7, 2048)  8192        ['conv5_block1_3_conv[0][0]']    
 ization)                                                                                         

 conv5_block1_add (Add)         (None, 7, 7, 2048)   0           ['conv5_block1_0_bn[0][0]',      
                                                                  'conv5_block1_3_bn[0][0]']      

 conv5_block1_out (Activation)  (None, 7, 7, 2048)   0           ['conv5_block1_add[0][0]']       

 conv5_block2_1_conv (Conv2D)   (None, 7, 7, 512)    1049088     ['conv5_block1_out[0][0]']       

 conv5_block2_1_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block2_1_conv[0][0]']    
 ization)                                                                                         

 conv5_block2_1_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block2_1_bn[0][0]']      
 n)                                                                                               

 conv5_block2_2_conv (Conv2D)   (None, 7, 7, 512)    2359808     ['conv5_block2_1_relu[0][0]']    

 conv5_block2_2_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block2_2_conv[0][0]']    
 ization)                                                                                         

 conv5_block2_2_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block2_2_bn[0][0]']      
 n)                                                                                               

 conv5_block2_3_conv (Conv2D)   (None, 7, 7, 2048)   1050624     ['conv5_block2_2_relu[0][0]']    

 conv5_block2_3_bn (BatchNormal  (None, 7, 7, 2048)  8192        ['conv5_block2_3_conv[0][0]']    
 ization)                                                                                         

 conv5_block2_add (Add)         (None, 7, 7, 2048)   0           ['conv5_block1_out[0][0]',       
                                                                  'conv5_block2_3_bn[0][0]']      

 conv5_block2_out (Activation)  (None, 7, 7, 2048)   0           ['conv5_block2_add[0][0]']       

 conv5_block3_1_conv (Conv2D)   (None, 7, 7, 512)    1049088     ['conv5_block2_out[0][0]']       

 conv5_block3_1_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block3_1_conv[0][0]']    
 ization)                                                                                         

 conv5_block3_1_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block3_1_bn[0][0]']      
 n)                                                                                               

 conv5_block3_2_conv (Conv2D)   (None, 7, 7, 512)    2359808     ['conv5_block3_1_relu[0][0]']    

 conv5_block3_2_bn (BatchNormal  (None, 7, 7, 512)   2048        ['conv5_block3_2_conv[0][0]']    
 ization)                                                                                         

 conv5_block3_2_relu (Activatio  (None, 7, 7, 512)   0           ['conv5_block3_2_bn[0][0]']      
 n)                                                                                               

 conv5_block3_3_conv (Conv2D)   (None, 7, 7, 2048)   1050624     ['conv5_block3_2_relu[0][0]']    

 conv5_block3_3_bn (BatchNormal  (None, 7, 7, 2048)  8192        ['conv5_block3_3_conv[0][0]']    
 ization)                                                                                         

 conv5_block3_add (Add)         (None, 7, 7, 2048)   0           ['conv5_block2_out[0][0]',       
                                                                  'conv5_block3_3_bn[0][0]']      

 conv5_block3_out (Activation)  (None, 7, 7, 2048)   0           ['conv5_block3_add[0][0]']       

 flatten (Flatten)              (None, 100352)       0           ['conv5_block3_out[0][0]']       

 batch_normalization (BatchNorm  (None, 100352)      401408      ['flatten[0][0]']                
 alization)                                                                                       

 input_2 (InputLayer)           [(None, 5)]          0           []                               

 dense (Dense)                  (None, 512)          51380736    ['batch_normalization[0][0]']    

 dense_2 (Dense)                (None, 128)          768         ['input_2[0][0]']                

 dropout (Dropout)              (None, 512)          0           ['dense[0][0]']                  

 dropout_1 (Dropout)            (None, 128)          0           ['dense_2[0][0]']                

 dense_1 (Dense)                (None, 256)          131328      ['dropout[0][0]']                

 dense_3 (Dense)                (None, 256)          33024       ['dropout_1[0][0]']              

 concatenate (Concatenate)      (None, 512)          0           ['dense_1[0][0]',                
                                                                  'dense_3[0][0]']                

 dense_4 (Dense)                (None, 512)          262656      ['concatenate[0][0]']            

 dropout_2 (Dropout)            (None, 512)          0           ['dense_4[0][0]']                

 dense_5 (Dense)                (None, 2)            1026        ['dropout_2[0][0]']              

==================================================================================================
Total params: 75,798,658
Trainable params: 56,475,906
Non-trainable params: 19,322,752
__________________________________________________________________________________________________
Epoch 1/100
10/10 [==============================] - 37s 3s/step - loss: 0.3064 - accuracy: 0.8647 - val_loss: 0.8259 - val_accuracy: 0.7228 - lr: 1.0000e-04
Epoch 2/100
10/10 [==============================] - 30s 3s/step - loss: 0.0181 - accuracy: 0.9967 - val_loss: 0.6969 - val_accuracy: 0.8119 - lr: 1.0000e-04
Epoch 3/100
10/10 [==============================] - 31s 3s/step - loss: 0.0479 - accuracy: 0.9868 - val_loss: 0.5572 - val_accuracy: 0.8911 - lr: 1.0000e-04
Epoch 4/100
10/10 [==============================] - 31s 3s/step - loss: 0.0049 - accuracy: 1.0000 - val_loss: 0.4223 - val_accuracy: 0.9307 - lr: 1.0000e-04
Epoch 5/100
10/10 [==============================] - 31s 3s/step - loss: 8.0926e-04 - accuracy: 1.0000 - val_loss: 0.3881 - val_accuracy: 0.9406 - lr: 1.0000e-04
Epoch 6/100
10/10 [==============================] - 30s 3s/step - loss: 0.0240 - accuracy: 0.9934 - val_loss: 0.3644 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 7/100
10/10 [==============================] - 34s 4s/step - loss: 0.0079 - accuracy: 0.9967 - val_loss: 0.3430 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 8/100
10/10 [==============================] - 31s 3s/step - loss: 0.0118 - accuracy: 0.9967 - val_loss: 0.3438 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 9/100
10/10 [==============================] - 40s 4s/step - loss: 3.8591e-04 - accuracy: 1.0000 - val_loss: 0.3370 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 10/100
10/10 [==============================] - 40s 4s/step - loss: 0.0013 - accuracy: 1.0000 - val_loss: 0.3303 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 11/100
10/10 [==============================] - 46s 5s/step - loss: 1.7116e-04 - accuracy: 1.0000 - val_loss: 0.3297 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 12/100
10/10 [==============================] - 34s 4s/step - loss: 1.6355e-04 - accuracy: 1.0000 - val_loss: 0.3202 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 13/100
10/10 [==============================] - 37s 4s/step - loss: 7.6577e-05 - accuracy: 1.0000 - val_loss: 0.3069 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 14/100
10/10 [==============================] - 37s 4s/step - loss: 0.0018 - accuracy: 1.0000 - val_loss: 0.3007 - val_accuracy: 0.9604 - lr: 1.0000e-04
Epoch 15/100
10/10 [==============================] - 39s 4s/step - loss: 0.0140 - accuracy: 0.9967 - val_loss: 0.2827 - val_accuracy: 0.9604 - lr: 1.0000e-04
Epoch 16/100
10/10 [==============================] - 36s 4s/step - loss: 0.0040 - accuracy: 0.9967 - val_loss: 0.2655 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 17/100
10/10 [==============================] - 52s 5s/step - loss: 1.7826e-04 - accuracy: 1.0000 - val_loss: 0.2550 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 18/100
10/10 [==============================] - 79s 7s/step - loss: 9.5676e-05 - accuracy: 1.0000 - val_loss: 0.2495 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 19/100
10/10 [==============================] - 39s 4s/step - loss: 0.0017 - accuracy: 1.0000 - val_loss: 0.2405 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 20/100
10/10 [==============================] - 42s 4s/step - loss: 2.8877e-04 - accuracy: 1.0000 - val_loss: 0.2384 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 21/100
10/10 [==============================] - 922s 102s/step - loss: 1.3320e-04 - accuracy: 1.0000 - val_loss: 0.2370 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 22/100
10/10 [==============================] - 86s 9s/step - loss: 0.0027 - accuracy: 1.0000 - val_loss: 0.2042 - val_accuracy: 0.9802 - lr: 1.0000e-04
Epoch 23/100
10/10 [==============================] - 81s 8s/step - loss: 6.8032e-04 - accuracy: 1.0000 - val_loss: 0.1427 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 24/100
10/10 [==============================] - 82s 8s/step - loss: 7.9499e-05 - accuracy: 1.0000 - val_loss: 0.1203 - val_accuracy: 0.9604 - lr: 1.0000e-04
Epoch 25/100
10/10 [==============================] - 75s 8s/step - loss: 0.0125 - accuracy: 0.9934 - val_loss: 0.1011 - val_accuracy: 0.9604 - lr: 1.0000e-04
Epoch 26/100
10/10 [==============================] - 74s 8s/step - loss: 4.6063e-04 - accuracy: 1.0000 - val_loss: 0.0961 - val_accuracy: 0.9703 - lr: 1.0000e-04
Epoch 27/100
10/10 [==============================] - 73s 8s/step - loss: 0.0190 - accuracy: 0.9934 - val_loss: 0.0110 - val_accuracy: 1.0000 - lr: 1.0000e-04
Epoch 28/100
10/10 [==============================] - 74s 7s/step - loss: 1.8729e-04 - accuracy: 1.0000 - val_loss: 0.0479 - val_accuracy: 0.9802 - lr: 1.0000e-04
Epoch 29/100
10/10 [==============================] - 40s 4s/step - loss: 5.2324e-05 - accuracy: 1.0000 - val_loss: 0.0751 - val_accuracy: 0.9802 - lr: 1.0000e-04
Epoch 30/100
10/10 [==============================] - 52s 5s/step - loss: 2.5285e-06 - accuracy: 1.0000 - val_loss: 0.0802 - val_accuracy: 0.9802 - lr: 1.0000e-04
Epoch 31/100
10/10 [==============================] - 59s 6s/step - loss: 1.4515e-05 - accuracy: 1.0000 - val_loss: 0.0764 - val_accuracy: 0.9802 - lr: 2.0000e-05
Epoch 32/100
10/10 [==============================] - 41s 4s/step - loss: 3.2284e-06 - accuracy: 1.0000 - val_loss: 0.0741 - val_accuracy: 0.9802 - lr: 2.0000e-05
Epoch 32: early stopping
4/4 [==============================] - 11s 2s/step
              precision    recall  f1-score   support

           0       0.94      1.00      0.97        30
           1       1.00      0.97      0.99        71

    accuracy                           0.98       101
   macro avg       0.97      0.99      0.98       101
weighted avg       0.98      0.98      0.98       101

Program running time: 2435.0641238689423
'''